import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';

import 'api_server.dart';
import 'config.dart';

class ResponseInterceptor extends Interceptor {
  @override
  Future<void> onResponse(
      Response response, ResponseInterceptorHandler handler) async {
    //处理最外层数据结构
    BaseResponse? bean = BaseResponse.fromJson(response.data);

    // 容错等处理 todo
    /*if (bean != null) if ((bean.data is Map && (bean.data as Map).isEmpty) ||
        (bean.data is String &&
            (bean.data == '' ||
                bean.data == 'null' ||
                bean.data == '[]' ||
                bean.data == '[[]]' ||
                bean.data == '{}'))) bean.data = null;*/

    if (bean?.errorCode == NetConfig.tokenInvalid) {
      await HostHttp.instance.notifyTokenInvalid();
      return;
    }

    response.data = bean;

    handler.next(response);
  }
}

const String jsonKeyBody = "Body";
const String jsonKeyCode = "ErrorCode";
const String jsonKeyMsg = "Msg";

class BaseResponse<R> {
  dynamic? data;
  int? errorCode;
  String? errorMsg;

  bool get ok {
    return errorCode == 0;
  }

  int get code {
    return errorCode ?? -999;
  }

  String? get msg {
    return errorMsg;
  }

  BaseResponse._({
    this.data,
    this.errorCode,
    this.errorMsg,
  });

/*  @override
  String toString() {
    return 'BaseResponse{data: $data, errorCode: $errorCode, errorMsg: $errorMsg}';
  }*/

  static BaseResponse<T>? fromJson<T>(Map<String, dynamic?>? map) {
    debugPrint('response.data：' + map.toString());

    return map == null
        ? null
        : BaseResponse._(
            data: map[jsonKeyBody],
            errorCode: map[jsonKeyCode],
            errorMsg: map[jsonKeyMsg],
          );
  }

/* static FutureOr<BaseResponse?> fromJso(Map<String, dynamic?>? map) async {
    return map == null
        ? null
        : BaseResponse._(
            data: map[jsonKeyBody],
            errorCode: map[jsonKeyCode],
            errorMsg: map[jsonKeyMsg],
          );
  }*/
}

class LoadingInterceptor extends Interceptor {
  bool needLoading = true;

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    onReq();
    handler.next(options);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    handler.next(response);
    onEnd();
  }

  void onReq() {
    //打开加载UI
    if (needLoading) {
      debugPrint('onRequest');
// tod o EasyDialog.showLoading();
    }
  }

  void onEnd() {
    debugPrint('onEnd');

    // tod o if (isLoading && EasyDialog.isExist()) EasyDialog.dismiss();,UI生命周期问
  }

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) {
    handler.next(err);
    onEnd();
  }
}

/// 错误处理拦截器
class ErrorInterceptor extends Interceptor {
  @override
  void onError(DioError err, ErrorInterceptorHandler handler) {
    // error统一处理
    AppException appException = AppException.init(err);

    err.error = appException;

    handler.next(err);
  }
}

/// 自定义异常
class AppException implements Exception {
  final String msg;
  final int code;

  AppException(this.code, this.msg);

  String toString() => "$code $msg";

  factory AppException.init(DioError error) {
    switch (error.type) {
      case DioErrorType.cancel:
        return AppException(-1, "请求取消");
      case DioErrorType.connectTimeout:
        return AppException(-1, "连接超时");
      case DioErrorType.sendTimeout:
        return AppException(-1, "请求超时");
      case DioErrorType.receiveTimeout:
        return AppException(-1, "响应超时");
      case DioErrorType.response:
        try {
          int errCode = error.response?.statusCode ?? -1;
          switch (errCode) {
            case 400:
              return AppException(errCode, "请求语法错误");
            case 401:
              return AppException(errCode, "没有权限");
            case 403:
              return AppException(errCode, "服务器拒绝执行");
            case 404:
              return AppException(errCode, "无法连接服务器");
            case 405:
              return AppException(errCode, "请求方法被禁止");
            case 500:
              return AppException(errCode, "服务器内部错误");
            case 502:
              return AppException(errCode, "无效的请求");
            case 503:
              return AppException(errCode, "服务器挂了");
            case 505:
              return AppException(errCode, "不支持HTTP协议请求");
            default:
              return AppException(
                  errCode, error.response?.statusMessage ?? '未知错误');
          }
        } catch (e) {
          return AppException(-1, "未知错误：${e.toString()}");
        }
      default:
        return AppException(-1, error.message);
    }
  }
}
